package com.sky.chapter3.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author : wushikai
 * <p>
 * date : 2022-07-04
 * ReentrantLock锁申请等待限时
 * <p>
 * 申请锁等待限时是什么意思？一般情况下，获取锁的时间我们是不知道的，synchronized关键字获取锁的过程中，
 * 只能等待其他线程把锁释放之后才能够有机会获取到锁。所以获取锁的时间有长有短。
 * 如果获取锁的时间能够设置超时时间，那就非常好了。
 * <p>
 * ReentrantLock刚好提供了这样功能，给我们提供了获取锁限时等待的方法tryLock()，可以选择传入时间参数，表示等待指定的时间，
 * 无参则表示立即返回锁申请的结果：true表示获取锁成功，false表示获取锁失败。
 */
public class LockDemo3 {
    private static ReentrantLock lock = new ReentrantLock(false);

    public static class MT0 extends Thread {
        MT0(String name) {
            super(name);
        }

        @Override
        public void run() {
            try {
                System.out.println(System.currentTimeMillis() + ":" + this.getName() + "开始获取锁!");
                //获取锁超时时间设置为3秒，3秒内是否能否获取锁都会返回
                if (lock.tryLock()) {
                    System.out.println(System.currentTimeMillis() + ":" + this.getName() + "获取到了锁!");
                    //获取到锁之后，休眠5秒
                    TimeUnit.SECONDS.sleep(5);
                } else {
                    System.out.println(System.currentTimeMillis() + ":" + this.getName() + "未能获取到锁!");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
        }




    }


    public static class MT1 extends Thread {
        MT1(String name) {
            super(name);
        }
        @Override
        public void run() {
            try {
                System.out.println(System.currentTimeMillis() + ":" + this.getName() + "开始获取锁!");
                //获取锁超时时间设置为3秒，3秒内是否能否获取锁都会返回
                if (lock.tryLock(3, TimeUnit.SECONDS)) {
                    System.out.println(System.currentTimeMillis() + ":" + this.getName() + "获取到了锁!");
                    //获取到锁之后，休眠5秒
                    TimeUnit.SECONDS.sleep(5);
                } else {
                    System.out.println(System.currentTimeMillis() + ":" + this.getName() + "未能获取到锁!");
                }
                System.out.println(System.currentTimeMillis() + ":" + this.getName() + " 返回!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
        }
    }


    public static void main(String[] args) throws InterruptedException {
      /*  MT MT1 = new MT("t1");
        MT MT2 = new MT("t2");
        MT1.start();
        MT2.start();*/

        MT1 mt11 = new MT1("mt11");
        MT1 mt12 = new MT1("mt12");
        mt11.start();
        mt12.start();

    }
}
